package com.trailwalker.traceability.util;

import com.google.gson.*;
import com.trailwalker.JavaUtils.log.LogUtils;
import com.trailwalker.JavaUtils.string.StringUtils;

import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GsonUtils {
    private static Gson gson = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class,
                    (JsonSerializer<LocalDateTime>) (src, typeOfSrc, context)
                            -> new JsonPrimitive(src.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))))
            .registerTypeAdapter(LocalDate.class,
                    (JsonSerializer<LocalDate>) (src, typeOfSrc, context)
                            -> new JsonPrimitive(src.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))))
            .registerTypeAdapter(LocalDateTime.class,
                    (JsonDeserializer<LocalDateTime>) (json, type, jsonDeserializationContext)
                            -> LocalDateTime.parse(json.getAsJsonPrimitive().getAsString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
            .registerTypeAdapter(LocalDate.class,
                    (JsonDeserializer<LocalDate>) (json, type, jsonDeserializationContext)
                            -> LocalDate.parse(json.getAsJsonPrimitive().getAsString(), DateTimeFormatter.ofPattern("yyyy-MM-dd")))
            .create();

    public static Gson getGson() {
        return gson;
    }

    public static String toJson(Object obj) {
        return gson.toJson(obj);
    }

    public static String toPrettyFormat(Object obj) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        return gson.toJson(obj);
    }


    public static <T> T loadAs(String json, Class<T> clazz) throws Exception {
        return gson.fromJson(json, clazz);
    }


    public static <T> T loadAs(String json, Type type) throws Exception {
        return gson.fromJson(json, type);
    }

    public static <T> ArrayList<T> loadAsList(String json, Class<T> cls) {
        ArrayList<T> mList = new ArrayList<T>();
        JsonArray array = new JsonParser().parse(json).getAsJsonArray();
        for (final JsonElement elem : array) {
            mList.add(GsonUtils.getGson().fromJson(elem, cls));
        }
        return mList;
    }

    public static String regexJson(String json) {
        //String s = "[{\"name\":\"jack\",\"data\":[\"11\",\"22\",\"33\",\"44\"]},{\"name\":\"rose\",\"data\":[\"11\",\"22\",\"33\",\"44\"]}]";
        String regex = "\"(\\d+)\"";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(json);
        while (matcher.find()) {
            String group = matcher.group();
            json = json.replace(group, group.substring(1, group.length() - 1));
        }
        return json;
    }

//    public static <T> List<T> loadAsList(String json, Class<T> clazz)
//            throws Exception {
//        return gson.fromJson(json, new TypeToken<List<T>>() {
//        }.getType());
//    }

    public static boolean isGoodJson(String json) {
        if (StringUtils.isEmpty(json)) {
            return false;
        }
        try {
            new JsonParser().parse(json);
            return true;
        } catch (Exception e) {
            LogUtils.logE(e);
            return false;
        }
    }
}
